/*
 * @Description: 
 * @Author: ldx
 * @Date: 2023-03-11 13:39:54
 * @LastEditors: ldx
 * @LastEditTime: 2023-04-28 12:07:00
 */

import { Vector3, Matrix4} from 'https://unpkg.com/three/build/three.module.js';

/**
 * gl：webgl上下文
 * type：着色器类型
 * source：着色器代码片段
 */
export function initShader(gl, type, source) {
  // 创建着色器对象
  const shader = gl.createShader(type)
  // 把着色器文件传入着色器对象中
  gl.shaderSource(shader, source)
  // 编译着色器对象
  gl.compileShader(shader)
  // 返回着色器对象
  return shader
}
/** 初始化程序对象 */
export function initProgram(gl) {
  // 创建程序对象
  const program = gl.createProgram()
  // 建立着色器对象
  const vertexShader = initShader(gl, gl.VERTEX_SHADER, document.querySelector('#vertex').innerHTML)
  const fragmentShader = initShader(gl, gl.FRAGMENT_SHADER, document.querySelector('#fragment').innerHTML)
  // 把着色器对象装进程序对象中去
  gl.attachShader(program, vertexShader)
  gl.attachShader(program, fragmentShader)
  // 链接webgl上下文对象和程序对象
  gl.linkProgram(program)
  // 启动程序对象
  gl.useProgram(program)
  // 把程序对象挂到上下文对象
  gl.program = program
  // 返回着色器是否成功编译和程序对象链接状态。
  return {
    vertex: gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS),
    fragment: gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS),
    program: gl.getProgramParameter(program, gl.LINK_STATUS)
  }
}
/** 获取鼠标在webgl中的坐标 */
export function getMousePosInWebgl({ clientX, clientY }, canvas) {
  // 获取canvas容器的一半宽高
  const halfW = canvas.clientWidth / 2
  const halfH = canvas.clientHeight / 2
  // 计算webgl坐标系下的鼠标位置
  const x = (clientX - halfW) / halfW
  const y = (halfH - clientY) / halfH
  return { x, y }
}

//线性比例尺
export function ScaleLinear(ax, ay, bx, by) {
  const delta = {
    x: bx - ax,
    y: by - ay,
  };
  const k = delta.y / delta.x;
  const b = ay - ax * k;
  return function (x) {
    return k * x + b;
  };
}

/* 正弦函数 */
export function SinFn(a, Omega, phi) {
  return function (x) {
    return a * Math.sin(Omega * x + phi);
  }
}

export function getViewMatrix(e,t,u){
  // 位移到原点
  const mt = new Matrix4().makeTranslation(-e.x,-e.y,-e.z)
  // 相机位置 - 目标位置，得到z轴正坐标（视线向量）
  const c = new Vector3().subVectors(e,t).normalize()
  // 上方向向量叉乘视线向量，得到x轴正坐标
  const a = new Vector3().crossVectors(u,c).normalize()
  // 视线分量叉乘x轴分量，得到y轴正坐标
  const b = new Vector3().crossVectors(c,a).normalize()
  // 正交矩阵的逆矩阵就是其转置矩阵。
  const mr = new Matrix4().set(
    ...a,0,
    ...b,0,
    -c.x,-c.y,-c.z,0,
    0,0,0,1
  )
  // 先平移在旋转
  return mr.multiply(mt).elements
}

/* GetIndexInGrid
  在由一维数组建立的栅格矩阵中，基于行列获取元素的索引位置
*/
export function GetIndexInGrid(w, size) {
  return function (x, y) {
    return (y * w + x) * size
  }
}

/* 对Image 加载事件的封装 */
export function imgPromise(img){
  return new Promise((resolve)=>{
    img.onload=function(){
        resolve(img);
    }
  });
}